#include <iostream>
#include <unistd.h>
#include <dirent.h> 
#include <list>

#include <ltdl.h>

#include "anal.h"

using namespace std;

typedef int   (*score_function_t)(uint32_t, AnalHost *);

class Module {
	string	name_;
	lt_dlhandle	hdl_;
	score_function_t	function_;
public:
	Module(string	name, lt_dlhandle	hdl, score_function_t	function) :
		name_(name), hdl_(hdl), function_(function) {}
	friend class ModuleList;
};

class ModuleList : public list<Module *> {
public:
	ModuleList(string moduleDir) {
		DIR           *dir;
		struct dirent *dent;

		dir = opendir(moduleDir.c_str());
		if (!dir) {
			perror(moduleDir.c_str());
			exit(1);
		}
		while ((dent = readdir(dir)) != NULL) {
			string	fname(dent->d_name);
			if (fname == "." || fname == "..")
				continue;
			int	loc;
			if ((loc = fname.rfind(".la")) != string::npos) {
				string	moduleName(fname, 0, loc);
				string	fullModulePath = moduleDir + string("/") + fname;
				lt_dlhandle hdl = lt_dlopen(fullModulePath.c_str());
				if (hdl == 0) {
					cerr << "lt_dlopen problem " << lt_dlerror() << endl;
					continue;
				} 
				score_function_t	fp = 0;
				string	scorer = string("score_") + moduleName;
				fp =  (score_function_t)lt_dlsym(hdl, scorer.c_str());
				if (fp == 0) {
					cerr << "lt_dlsym error in scorer '" << scorer << "' " << lt_dlerror() << endl;
					continue;
				}
				push_back(new Module(moduleName, hdl, fp));
				cout << "loaded '" << fname << "'" << endl;
			}
		}
		closedir(dir);
	}
	void	runAllTests(HostMap *hm) {
		for (HostMap::iterator hmiter = hm->begin(); hmiter != hm->end();  hmiter++) {
			for (list<Module *>::iterator iter = begin(); iter != end();  iter++) {
				Module *mod = (*iter);
				mod->function_((*hmiter).first, (*hmiter).second);
			}
		}
	}
};

int	main(int argc, char *argv[])
{
	int	opt;
	const char	*lmask = 0;
	int	recentSeconds = 0;
	char	*gateway = 0;

	while ((opt = getopt(argc, argv, "g:l:r:")) != -1) {
		switch (opt) {
		case 'g':
			gateway = optarg;
			break;
		case 'l':
			lmask = optarg;
			break;
		case 'r':
			recentSeconds = atoi(optarg);
			break;
		default:
			cerr << "invalid usage" << endl;
			cerr << "-l <local network mask>" << endl;
			exit(1);
		}
	}
	cout << "hogs" << endl;
	extern void	SQLConnect(const char *connectionInfo);

	SQLConnect("DSN=mysqltcap");

	extern HostMap 	*SQLRead(const char *local_mask, int recentSeconds, char *gateway);
	HostMap *hm = SQLRead(lmask, recentSeconds, gateway);
//	LTDL_SET_PRELOADED_SYMBOLS();

	lt_dlinit();

	ModuleList	ml("../modules/src");

	ml.runAllTests(hm);
#if 0
	lt_dlhandle hdl = lt_dlopen("../modules/src/tanal_modules.la");
	if (hdl == 0) {
		cerr << lt_dlerror() << endl;
	} 

	score_function_t	fp = 0;
	fp =  (score_function_t)lt_dlsym(hdl, "Score_bt");
	if (fp == 0) {
		cerr << "BAD dlsym" << lt_dlerror() << endl;
	}
	fp(hm);
#endif
	cout << "DONE" << endl;

//	cout << *hm;
	return 0;
}
